local msghelper = require "tablehelper"
local math_random = math.random
local timetool = require "timetool"
local timer = require "timer"
local filelog = require "filelog"
local cardtool = require "cardtool"
local tabletool = require "tabletool"
local skynet = require "skynet"
local json = require "cjson"
json.encode_sparse_array(true,1,1)
local robotbase = require "robot"
local table_insert = table.insert
require "pszenum"
require "cardvalue"

local tablelogic	-- = require("tablelogic")
local seatlogic		-- = require("seatlogic")
local server
local table_data
local robot = robotbase:new()

local GameLogic = {}
function GameLogic.init(tablebase)
	server = tablebase
	tablelogic = tablebase.logic.tablelogic
	seatlogic  = tablebase.logic.seatlogic
	table_data = tablebase.table_data
	return true
end

function GameLogic.getnextplayer(seat_index) --获取座位+1 的玩家
	local seatindex = seat_index 
	repeat
		seatindex = seatindex + 1
		if seatindex > #table_data.seats then
			seatindex = 1
		end
		local seat = table_data.seats[seatindex]
		if seat.state > ESeatState.SEAT_STATE_NO_PLAYER then
			return seatindex
		end
	until seatindex == seat_index
	return nil
end

function GameLogic.getnextgameplayer(seat_index) --获取座位+1 的游戏玩家
	local seatindex = seat_index or 1
	repeat
		seatindex = seatindex + 1
		if seatindex > #table_data.seats then
			seatindex = 1
		end
		local seat = table_data.seats[seatindex]
		if seatindex ~= seat_index then
			if GameLogic.is_playing(seat) == true then
				return seatindex
			end
		end
	until seatindex == seat_index
	return nil
end

function GameLogic.gamestart()
	if table_data.timer_id and table_data.timer_id > 0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end
	-- 启动开始倒计时定时器，在定时器超时函数中处理发牌逻辑
	local count = table_data.conf.match_type and 3 or 0
	if table_data.the_round > 1 then count = 0 end
	local timerid = timer.settimer(count*100, "onegamestart")
	table_data.timer_id = timerid
end

function GameLogic.onegamestart()
	local now = timetool.get_time()
	--初始化桌子
	GameLogic.onegamestart_inittable()
	tablelogic.randcardlist4seat(table_data)

	local rids = {}
	local players = {}
	local playerdata = {}
	-- 设置玩家状态为开始游戏
	for _, seat in ipairs(table_data.seats) do
		if seat.state == ESeatState.SEAT_STATE_WAIT_START then
			GameLogic.onegamestart_initseat(seat)
			seat.state = ESeatState.SEAT_STATE_PLAYING

			table_data.playernum = table_data.playernum + 1
			table_data.start_playernum = table_data.playernum   --开局桌位玩家数
			table_insert(players, seat.index)
			table.insert(rids, seat.rid)
			playerdata[seat.rid] = {
				name = seat.playerinfo.rolename,
				logo = seat.playerinfo.logo,
				sex = seat.playerinfo.sex,
				diamond = seat.diamond,
			}

			if seat.isrobot then
				seat.playgamecount = (seat.playgamecount or 0) + 1
			end
		end
	end
	table.sort(rids, function(l, r)
		return l < r
	end)
	local ridsstr = ''
	for _, rid in ipairs(rids) do
		if ridsstr == '' then
			ridsstr = ridsstr .. rid
		else
			ridsstr = ridsstr .. '_' .. rid
		end
	end
	-- init gamerecords
	table_data.gamerecords.start_time = now
	table_data.gamerecords.table_uuid = skynet.getenv("nodename") .. "_"
		.. table_data.conf.table_code .. "_"
		.. table_data.conf.idx .. "_" .. table_data.conf.create_time
	table_data.gamerecords.logname = '' .. table_data.gamerecords.table_uuid .. '_'
		.. now .. '_' .. '0' .. '_'
		.. ridsstr .. '_' .. os.date("%Y%m%d_%H%M%S", now) .. '_'
		.. table_data.conf.game_room_type
	table_data.gamerecords.conf = tabletool.deepcopy(table_data.conf)
	table_data.gamerecords.rids = ridsstr
	table_data.gamerecords.playerdata = json.encode(playerdata)
	--[[
	if table_data.conf.room_type == ERoomType.ROOM_TYPE_DIAMOND
	or table_data.conf.room_type == ERoomType.ROOM_TYPE_COIN
	or table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_DIAMOND then
		tablelogic.pay_tip(table_data)	-- 一定要放在onegamestart_initseat后
        --游戏开始扣除奖池抽水
        tablelogic.pay_jackopt(table_data)
	end
	--]]

	table_data.conf.curr_round_code = string.sub(tostring(now), -4, -1)
	table_data.gamerecords.conf.curr_round_code = table_data.conf.curr_round_code

	local seat_index = table_data.winer_index or players[math_random(1, table_data.start_playernum)]
	table_data.makers = seat_index
	seat_index = GameLogic.getnextgameplayer(seat_index)
	if seat_index == nil then
		filelog.sys_error("onegamestart seat_index == nil")
	end
	if table_data.seats[seat_index].rid <= 0 then
		seat_index = players[math_random(1, table_data.start_playernum)]
	end

	table_data.gamerecords.conf.table_makers = seat_index
	table_data.gamerecords.conf = json.encode(table_data.gamerecords.conf)
	tablelogic.save_actions(table_data)

	table_data.seat_index = seat_index
	table_data.action_to_time = timetool.get_time() + table_data.conf.action_timeout

	table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
	local gamestartntcmsg = {}
	gamestartntcmsg.gameinfo = {}
	msghelper:copy_table_gameinfo(gamestartntcmsg.gameinfo)
	msghelper:sendmsg_to_alltableplayer("gamestartN", gamestartntcmsg)

	table_data.seats[seat_index].action_times = 1
	--下发当前玩家操作协议	
	local doactionntcmsg = {
		rid = table_data.seats[seat_index].rid,
		seat_index = seat_index,
		action_to_time = timetool.get_time() + table_data.conf.action_timeout,
		game_turns = table_data.turns,
	}
	msghelper:sendmsg_to_alltableplayer("todoN", doactionntcmsg)

	table_data.timer_id = timer.settimer(table_data.conf.action_timeout*100, "doaction", doactionntcmsg)
	
	if table_data.conf.game_type > 2 and table_data.turns < 3 then
		skynet.fork(function()
			skynet.sleep(100)
			if table_data.state == ETableState.TABLE_STATE_GAME_END then return end
			local request = {
				action_type = EActionType.ACTION_TYPE_CALL,
				rid = table_data.seats[seat_index].rid,
			}
			tablelogic.doaction(table_data, request, table_data.seats[seat_index])
		end)
	else
		-------------------------- robot --------------------------
		-- if table_data.seats[seat_index].isrobot then
		if table_data.seats[seat_index].isrobot or table_data.seats[seat_index].istest then	-- test
			skynet.fork(function()
				skynet.sleep(math_random(2, 3) * 100)
				local seat = table_data.seats[seat_index]
				local request = {
					action_type = EActionType.ACTION_TYPE_CALL,
					rid = seat.rid,
				}
				local status, inventory = skynet.pcall(skynet.call, ".slotmgr", "lua", "get_service_income", tablelogic.get_gamename(table_data))
				if not status then inventory = 0 end
				local result = robot:analyse(table_data, seat, inventory)
				-- filelog.warn("game start analyse result:", result, inventory)
				request.action_type, request.action_param = result[1], result[2]
				if request.action_type == EActionType.ACTION_TYPE_FOLD then
					if seat.seecards == 0 then
						request.action_type = EActionType.ACTION_TYPE_SEECARDS
						tablelogic.doaction(table_data, request, seat)
						skynet.sleep(math_random(2, 3) * 100)
						if table_data.state == ETableState.TABLE_STATE_GAME_END then
							return
						end
						if GameLogic.get_playingnum() == 2 then
							if inventory <= 0 then
								request.action_type = EActionType.ACTION_TYPE_FOLD
							else
								if cardtool.getCardType(seat.cards) == 0 and seat.cards[3].card_value < 13 then
									request.action_type = EActionType.ACTION_TYPE_FOLD
								else
									if math_random(100) <= 80 then
										request.action_type = EActionType.ACTION_TYPE_CALL
									else
										request.action_type = EActionType.ACTION_TYPE_FOLD
									end
								end
							end
						else
							request.action_type = EActionType.ACTION_TYPE_FOLD
						end
					end
				elseif request.action_type == EActionType.ACTION_TYPE_RAISE then
					if seat.seecards == 0 then
						request.action_type = EActionType.ACTION_TYPE_SEECARDS
						tablelogic.doaction(table_data, request, seat)
						skynet.sleep(math_random(2, 3) * 100)
						if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
						request.action_type = EActionType.ACTION_TYPE_RAISE	-- 参数到目前还是加注的参数
					end
				end

				tablelogic.doaction(table_data, request, seat)
			end)
		end

		skynet.fork(function()
			local request = {
				action_type = EActionType.ACTION_TYPE_CALL,
			}
			for _, seat in ipairs(table_data.seats) do
				if seat.isrobot and seat.index ~= seat_index and seat.seecards == 0 then
					if math_random(100) <= 10 then
						request.action_type = EActionType.ACTION_TYPE_SEECARDS
						request.rid = seat.rid
						skynet.sleep(math_random(2, 3) * 100)
						if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
						tablelogic.doaction(table_data, request, seat)
					end
				end
			end
		end)
	end

    --[[保存牌型记录
    local playernum = 0
    local cardtypes = {}
    for _, seat in pairs(table_data.seats) do
        if seat.state == ESeatState.SEAT_STATE_PLAYING then
            local card_type = cardtool.getCardType(seat.cards)
            if card_type == CardType.BAO_ZI then    --3A单独算
                if seat.cards[1].card_value == 14 then
                    card_type = card_type + 1
                end
            end
            playernum = playernum + 1
            table.insert(cardtypes,card_type)
        end
    end
    tablelogic.save_cardtype_record(table_data.conf.game_type, cardtypes, playernum)
	--]]
end

function GameLogic.todonotice(nowindex)
	table_data.seat_index = GameLogic.getnextgameplayer(nowindex)

	if table_data.forcecomparing then
		GameLogic.forcecompare()
		return
	end

	local nextseat = table_data.seats[table_data.seat_index]
	table_data.action_to_time = timetool.get_time() + table_data.conf.action_timeout

	nextseat.action_times = (nextseat.action_times or 0) + 1
	for i, v in ipairs(table_data.seats) do
		if v.state == ESeatState.SEAT_STATE_PLAYING or v.state == ESeatState.SEAT_STATE_CALL or v.state == ESeatState.SEAT_STATE_RAISE then
			if (v.action_times or 0) > table_data.turns then
				table_data.turns = v.action_times - 1
			end
		end
	end

	if table_data.turns >= table_data.conf.force_overturns then
		table_data.forcecomparing = true
		msghelper:sendmsg_to_alltableplayer("forcecompareN", {})
		table_data.timer_id = timer.settimer(2*100, "forcecompare")
		return
	end

	local doactionntcmsg = {
		rid = table_data.seats[table_data.seat_index].rid,
		seat_index = table_data.seat_index,
		action_to_time = table_data.action_to_time,
		game_turns = table_data.turns,
	}

	if table_data.conf.game_type > 2 and table_data.turns < 3 then
		skynet.fork(function()
			skynet.sleep(100)
			if table_data.state == ETableState.TABLE_STATE_GAME_END then return end
			local request = {
				action_type = EActionType.ACTION_TYPE_CALL,
				rid = nextseat.rid,
			}
			tablelogic.doaction(table_data, request, nextseat)
		end)
	-- elseif nextseat.isrobot then
	elseif nextseat.isrobot or nextseat.istest then	-- test
		msghelper:sendmsg_to_alltableplayer("todoN", doactionntcmsg)
		if table_data.todo_time_id and table_data.todo_time_id > 0 then
			timer.cleartimer(table_data.todo_time_id)
			table_data.todo_time_id = -1
		end
		-------------------------- robot --------------------------
		skynet.fork(function()
			skynet.sleep(math_random(1, 3) * 100)

			if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end

			local request = {
				action_type = EActionType.ACTION_TYPE_CALL,
				rid = nextseat.rid,
			}

			if nextseat.seecards == 0 then
				if math_random(100) <= 20 * (table_data.robotdata.seecardscount + 1) then
					request.action_type = EActionType.ACTION_TYPE_SEECARDS
					tablelogic.doaction(table_data, request, nextseat)
					skynet.sleep(math_random(2, 4) * 100)
					if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
				end
			end

			local status, inventory = skynet.pcall(skynet.call, ".slotmgr", "lua", "get_service_income", tablelogic.get_gamename(table_data))
			if not status then inventory = 0 end
			local result = robot:analyse(table_data, nextseat, inventory)
			-- filelog.warn("analyse result:", result, inventory)
			request.action_type, request.action_param = result[1], result[2]
			if request.action_type == EActionType.ACTION_TYPE_FOLD then
				if nextseat.seecards == 0 then
					request.action_type = EActionType.ACTION_TYPE_SEECARDS
					tablelogic.doaction(table_data, request, nextseat)
					skynet.sleep(math_random(2, 4) * 100)
					if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
					if GameLogic.get_playingnum() == 2 then
						if inventory <= 0 then
							request.action_type = EActionType.ACTION_TYPE_FOLD
						else
							if cardtool.getCardType(nextseat.cards) == 0 and nextseat.cards[3].card_value < 12 then
								request.action_type = EActionType.ACTION_TYPE_FOLD
							else
								-- 弃牌触发比牌，需要保证至少有一次跟注或者加注
								if (table_data.robotdata.seats[nextseat.index].actioncount or 0) > 0 then
									if math_random(100) <= 80 then
										request.action_type = EActionType.ACTION_TYPE_COMPARE
										request.action_param = GameLogic.getnextgameplayer(nextseat.index)
									else
										request.action_type = EActionType.ACTION_TYPE_FOLD
									end
								else
									if math_random(100) <= 80 then
										request.action_type = EActionType.ACTION_TYPE_CALL
									else
										request.action_type = EActionType.ACTION_TYPE_FOLD
									end
								end
							end
						end
					else
						request.action_type = EActionType.ACTION_TYPE_FOLD
					end
				end
			elseif request.action_type == EActionType.ACTION_TYPE_COMPARE then
				if nextseat.seecards == 0 then
					if GameLogic.get_playingnum() == 2 then
						if math_random(100) <= 60 then
							request.action_type = EActionType.ACTION_TYPE_SEECARDS
							tablelogic.doaction(table_data, request, nextseat)
							skynet.sleep(math_random(2, 4) * 100)
							if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
						end
						request.action_type = EActionType.ACTION_TYPE_COMPARE
					else
						request.action_type = EActionType.ACTION_TYPE_SEECARDS
						tablelogic.doaction(table_data, request, nextseat)
						skynet.sleep(math_random(2, 4) * 100)
						if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
						request.action_type = EActionType.ACTION_TYPE_COMPARE
					end
				end
			elseif request.action_type == EActionType.ACTION_TYPE_RAISE then
				if nextseat.seecards == 0 then
					request.action_type = EActionType.ACTION_TYPE_SEECARDS
					tablelogic.doaction(table_data, request, nextseat)
					skynet.sleep(math_random(2, 3) * 100)
					if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
					request.action_type = EActionType.ACTION_TYPE_RAISE	-- 参数到目前还是加注的参数
				end
			end
			if table_data.state >= ETableState.TABLE_STATE_GAME_END then return end
			tablelogic.doaction(table_data, request, nextseat)
		end)
	else
		table_data.todo_time_id = timer.settimer(40, "todonotice", doactionntcmsg)
	end

	table_data.timer_id = timer.settimer(table_data.conf.action_timeout*100, "doaction", doactionntcmsg)
end

GameLogic.actions = {
	[EActionType.ACTION_TYPE_CALL] = function(seat, param)	-- [1] 跟注
		local noticemsg = {
			rid = seat.rid,
			seat_index = table_data.seat_index,
			action_type = table_data.action_type,
			action_param = param,
			cur_bets = table_data.cur_bets,
			all_bets = table_data.all_bets,
		}
		table_data.robotdata.seats[seat.index].actioncount = (table_data.robotdata.seats[seat.index].actioncount or 0) + 1
		local bets = table_data.cur_bets
		seat.state = ESeatState.SEAT_STATE_CALL  

		if seat.seecards > 0 then --看牌玩家加倍
			bets = bets * 2
		end

		tablelogic.change_money(table_data,seat,-bets) --扣钱     
		table_data.all_bets = table_data.all_bets + bets   --总投注增加

		noticemsg.cur_bets = table_data.cur_bets
		noticemsg.all_bets = table_data.all_bets
		noticemsg.seat_all_bets = seat.diamond_base - seat.diamond
		msghelper:sendmsg_to_alltableplayer("doactionN", noticemsg)
		local action = timetool.get_time() .. "_"
			.. seat.rid .. "_"
			.. (table_data.action_type or '0') .. "_"
			.. (param or '0') .. "_"
			.. (table_data.all_bets or '0') .. "_"
			.. (table_data.turns or '0')
		tablelogic.save_actions(table_data, action)

		table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
		GameLogic.todonotice(seat.index)
	end,

	[EActionType.ACTION_TYPE_RAISE] = function(seat, param)	-- [2] 加注
		local noticemsg = {
			rid = seat.rid,
			seat_index = table_data.seat_index,
			action_type = table_data.action_type,
			action_param = param,
			cur_bets = table_data.cur_bets,
			all_bets = table_data.all_bets,
		}
		table_data.robotdata.seats[seat.index].actioncount = (table_data.robotdata.seats[seat.index].actioncount or 0) + 1
		local bets = table_data.conf.base_score * param
		seat.state = ESeatState.SEAT_STATE_RAISE

		if bets > table_data.cur_bets then --当前的底注增加
			table_data.cur_bets = bets
		end

		if seat.seecards > 0 then --看牌玩家加倍
			bets = bets * 2
		end

		tablelogic.change_money(table_data,seat,-bets) --扣钱     
		table_data.all_bets = table_data.all_bets + bets   --总投注增加

		noticemsg.cur_bets = table_data.cur_bets
		noticemsg.all_bets = table_data.all_bets
		noticemsg.seat_all_bets = seat.diamond_base - seat.diamond
		msghelper:sendmsg_to_alltableplayer("doactionN", noticemsg)
		local action = timetool.get_time() .. "_"
			.. seat.rid .. "_"
			.. (table_data.action_type or '0') .. "_"
			.. (param or '0') .. "_"
			.. (table_data.all_bets or '0') .. "_"
			.. (table_data.turns or '0')
		tablelogic.save_actions(table_data, action)

		GameLogic.todonotice(seat.index)
		table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
	end,

	[EActionType.ACTION_TYPE_COMPARE] = function(seat, param, isforce)	-- [3] 比牌
		table_data.comparing = true
		local compareseat = table_data.seats[param]
		if compareseat.state == ESeatState.SEAT_STATE_FOLD then
			table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
			table_data.comparing = nil
			filelog.sys_error(compareseat.rid, "has folded!")
			return
		end

		local noticemsg = {
			rid = seat.rid,
			seat_index = table_data.seat_index,
			action_type = table_data.action_type,
			action_param = param,
			cur_bets = table_data.cur_bets,
			all_bets = table_data.all_bets,
		}
		if not isforce then
			local bets = table_data.cur_bets
			if seat.seecards > 0 then --看牌玩家加倍
				bets = bets * 2
			end
			tablelogic.change_money(table_data,seat,-bets)	--扣钱
			table_data.all_bets = table_data.all_bets + bets	--总投注增加
		end

		local action = timetool.get_time() .. "_"
			.. seat.rid .. "_"
			.. (table_data.action_type or '0') .. "_"
			.. (param or '0') .. "_"
			.. (table_data.all_bets or '0') .. "_"
			.. (table_data.turns or '0')
		tablelogic.save_actions(table_data, action)

		skynet.fork(function()
			local compareplayer = {
				seat = seat.index,
				compare_seat = compareseat.index,
			}
			if not isforce then
				if compareseat.state == ESeatState.SEAT_STATE_FOLD then
					table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
					table_data.comparing = nil
					filelog.sys_error("target has folded!")
					return
				end

				msghelper:sendmsg_to_alltableplayer("compareplayerN", compareplayer)
				skynet.sleep(2 * 100)
				if table_data.state >= ETableState.TABLE_STATE_GAME_END then
					table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
					table_data.comparing = nil
					return
				end
			end

			if cardtool.isOvercomePrev(seat.cards, compareseat.cards) then
				if not isforce then
					noticemsg.action_param = seat.index
					noticemsg.cur_bets = table_data.cur_bets
					noticemsg.all_bets = table_data.all_bets
					noticemsg.seat_all_bets = seat.diamond_base - seat.diamond
					msghelper:sendmsg_to_alltableplayer("doactionN", noticemsg)
				end
				
				GameLogic.pay_money(compareseat, table_data.action_type)
				compareseat.state = ESeatState.SEAT_STATE_COMPARE_FAIL
				seat.compared = seat.compared or {}
				seat.compared[compareseat.index] = 1
				compareseat.compared = compareseat.compared or {}
				compareseat.compared[seat.index] = 1
				seat.comparewin = seat.comparewin + math_random(2)

				local seatstatusmsg = {
					rid = compareseat.rid,
					seat_index = compareseat.index,
					seat_status = compareseat.state,
					seecards = compareseat.seecards,
				}
				seatstatusmsg.cards = {}
				msghelper:sendmsg_to_alltableplayer("seatstatusN", seatstatusmsg)

				local action_lose = timetool.get_time() .. "_"
					.. compareseat.rid .. "_"
					.. "-1" .. "_"
					.. '0' .. "_"
					.. (table_data.all_bets or '0') .. "_"
					.. (table_data.turns or '0')
				tablelogic.save_actions(table_data, action_lose)
			else
				if not isforce then
					noticemsg.action_param = compareseat.index
					noticemsg.cur_bets = table_data.cur_bets
					noticemsg.all_bets = table_data.all_bets
					noticemsg.seat_all_bets = seat.diamond_base - seat.diamond
					msghelper:sendmsg_to_alltableplayer("doactionN", noticemsg)
				end
				
				GameLogic.pay_money(seat, table_data.action_type)
				seat.state = ESeatState.SEAT_STATE_COMPARE_FAIL
				seat.compared = seat.compared or {}
				seat.compared[compareseat.index] = 1
				compareseat.compared = compareseat.compared or {}
				compareseat.compared[seat.index] = 1
				compareseat.comparewin = compareseat.comparewin + math_random(2)

				local seatstatusmsg = {
					rid = seat.rid,
					seat_index = seat.index,
					seat_status = seat.state,
					seecards = seat.seecards,
				}
				seatstatusmsg.cards = {}
				msghelper:sendmsg_to_alltableplayer("seatstatusN", seatstatusmsg)

				local action_lose = timetool.get_time() .. "_"
					.. seat.rid .. "_"
					.. "-1" .. "_"
					.. '0' .. "_"
					.. (table_data.all_bets or '0') .. "_"
					.. (table_data.turns or '0')
				tablelogic.save_actions(table_data, action_lose)
			end

			local isendgame, winseat = GameLogic.canendgame()
			if isendgame then --判断是否结束游戏
				table_data.state = ETableState.TABLE_STATE_GAME_END
				tablelogic.change_money(table_data, winseat, table_data.all_bets) --加钱
				GameLogic.pay_money(winseat)
				
				GameLogic.onegameend()
			else
				table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
				GameLogic.todonotice(seat.index)
			end
			table_data.comparing = nil
		end)
	end,

	[EActionType.ACTION_TYPE_SEECARDS] = function(seat, param)	-- [4] 看牌
		local noticemsg = {
			rid = seat.rid,
			seat_index = table_data.seat_index,
			action_type = table_data.action_type,
			action_param = param,
			cur_bets = table_data.cur_bets,
			all_bets = table_data.all_bets,
		}

		local seatstatusmsg = {
			rid = seat.rid,
			seat_index = seat.index,
			seat_status = seat.state,
			seecards = 1,
		}
		seat.seecards = 1 
		seatstatusmsg.cards = seat.cards --玩家游戏数据
		msghelper:sendmsg_to_tableplayer(seat, "seatstatusN", seatstatusmsg)
		-- seatstatusmsg.cards = {}
		-- msghelper:sendmsg_to_alltableplayer("seatstatusN", seatstatusmsg)

		noticemsg.cur_bets = table_data.cur_bets
		noticemsg.all_bets = table_data.all_bets
		noticemsg.seat_all_bets = seat.diamond_base - seat.diamond
		msghelper:sendmsg_to_alltableplayer("doactionN", noticemsg)
		local action = timetool.get_time() .. "_"
			.. seat.rid .. "_"
			.. (table_data.action_type or '0') .. "_"
			.. (param or '0') .. "_"
			.. (table_data.all_bets or '0') .. "_"
			.. (table_data.turns or '0')
		tablelogic.save_actions(table_data, action)
	end,

	[EActionType.ACTION_TYPE_FOLD] = function(seat, param)	-- [5] 弃牌
		local noticemsg = {
			rid = seat.rid,
			seat_index = table_data.seat_index,
			action_type = table_data.action_type,
			action_param = param,
			cur_bets = table_data.cur_bets,
			all_bets = table_data.all_bets,
		}
		
		local seatstatusmsg = {
			rid = seat.rid,
			seat_index = seat.index,
			seat_status = seat.state,
			seecards = seat.seecards
		}
		if seat.state == ESeatState.SEAT_STATE_FOLD or seat.state == ESeatState.SEAT_STATE_COMPARE_FAIL then
			filelog.sys_error(seat.rid, "has folded!")
			return
		end
		seat.state = ESeatState.SEAT_STATE_FOLD
		seatstatusmsg.seat_status = seat.state
		seatstatusmsg.cards = {}
		msghelper:sendmsg_to_alltableplayer("seatstatusN", seatstatusmsg)
		GameLogic.pay_money(seat, table_data.action_type)

		noticemsg.cur_bets = table_data.cur_bets
		noticemsg.all_bets = table_data.all_bets
		noticemsg.seat_all_bets = seat.diamond_base - seat.diamond
		msghelper:sendmsg_to_alltableplayer("doactionN", noticemsg)
		local action = timetool.get_time() .. "_"
			.. seat.rid .. "_"
			.. (table_data.action_type or '0') .. "_"
			.. (param or '0') .. "_"
			.. (table_data.all_bets or '0') .. "_"
			.. (table_data.turns or '0')
		tablelogic.save_actions(table_data, action)

		local isendgame, winseat = GameLogic.canendgame()
		if isendgame then --判断是否结束游戏
			table_data.state = ETableState.TABLE_STATE_GAME_END
			tablelogic.change_money(table_data, winseat, table_data.all_bets) --加钱
			GameLogic.pay_money(winseat)
			
			GameLogic.onegameend()
			return
		end

		if seat.index == table_data.seat_index then
			if table_data.timer_id and table_data.timer_id > 0 then
				timer.cleartimer(table_data.timer_id)
				table_data.timer_id = -1
			end

			table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
			GameLogic.todonotice(seat.index)
		end
	end,
}

function GameLogic.forcecompare() --游戏最后1圈时强制比牌
	local seat = table_data.seats[table_data.seat_index]
	local request = {
		action_type = EActionType.ACTION_TYPE_COMPARE,
		rid = seat.rid,
	}
	request.action_param = GameLogic.getnextgameplayer(seat.index)
	tablelogic.doaction(table_data, request, seat, true)
end

local function gamebalance(table_data)
	local balance = {}
	for _, seat in ipairs(table_data.seats) do
		if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			local noticemsg = {
				rid = seat.rid,
				seat_index = seat.index,
				diamond = seat.diamond,
				all_bets = table_data.all_bets,
				compare_player_info = {},
			}
			if seat.state ~= ESeatState.SEAT_STATE_WATCHING then
				table_insert(noticemsg.compare_player_info, {
					rid = seat.rid,
					seat_index = seat.index,
					rolename = seat.playerinfo.rolename,
					logo = seat.playerinfo.logo,
					lose_money = seat.diamond - seat.diamond_base,
					lose_diamond = seat.diamond - seat.diamond_base,
					lose_coin = 0,
					card_type = cardtool.getCardType(seat.cards) or -1,
					cards = tabletool.deepcopy(seat.cards),
				})
			end
			for _, value in ipairs(table_data.seats) do
				if seat.compared and seat.compared[value.index] then
					if value.rid > 0 and value.state ~= ESeatState.SEAT_STATE_WATCHING then
						table_insert(noticemsg.compare_player_info, {
							rid = value.rid,
							seat_index = value.index,
							rolename = value.playerinfo.rolename,
							logo = value.playerinfo.logo,
							lose_money = value.diamond - value.diamond_base,
							lose_diamond = value.diamond - value.diamond_base,
							lose_coin = 0,
							card_type = cardtool.getCardType(value.cards) or -1,
							cards = tabletool.deepcopy(value.cards),
						})
					end
				else
					if value.index ~= seat.index then
						if value.rid > 0 and value.state ~= ESeatState.SEAT_STATE_WATCHING then
							table_insert(noticemsg.compare_player_info, {
								rid = value.rid,
								seat_index = value.index,
								rolename = value.playerinfo.rolename,
								logo = value.playerinfo.logo,
								lose_money = value.diamond - value.diamond_base,
								lose_diamond = value.diamond - value.diamond_base,
								lose_coin = 0,
								card_type = -1,
								cards = {},
							})
						end
					end
				end
			end
			if table_data.leaves then
				for i, v in pairs(table_data.leaves) do
					if v.rid > 0 then
						if seat.compared and seat.compared[i] then
							table_insert(noticemsg.compare_player_info, v)
						else
							table_insert(noticemsg.compare_player_info, {
								rid = v.rid,
								seat_index = v.seat_index,
								rolename = v.rolename,
								logo = v.logo,
								lose_money = v.lose_money,
								lose_diamond = v.lose_money,
								lose_coin = 0,
								card_type = -1,
								cards = {},
							})
						end
					end
				end
			end
			balance[seat.rid] = noticemsg
			-- filelog.debug("gamebalanceN:", noticemsg)
			msghelper:sendmsg_to_tableplayer(seat, "gamebalanceN", noticemsg)
		end
	end
	tablelogic.save_actions(table_data, json.encode(balance))
end

local function coingamebalance(table_data)
	local balance = {}
	for _, seat in ipairs(table_data.seats) do
		if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			local noticemsg = {
				rid = seat.rid,
				seat_index = seat.index,
				diamond = seat.diamond,
				all_bets = table_data.all_bets,
				compare_player_info = {},
			}
			if seat.state ~= ESeatState.SEAT_STATE_WATCHING then
				local losediamond = 0
				if table_data.tmpdiamond.diamond and table_data.tmpdiamond.diamond[seat.rid] then
					losediamond = table_data.tmpdiamond.diamond[seat.rid].value
				end
				table_insert(noticemsg.compare_player_info, {
					rid = seat.rid,
					seat_index = seat.index,
					rolename = seat.playerinfo.rolename,
					logo = seat.playerinfo.logo,
					lose_money = seat.diamond - seat.diamond_base,
					lose_coin = table_data.tmpdiamond.coin[seat.rid].value,
					lose_diamond = losediamond,
					card_type = cardtool.getCardType(seat.cards) or -1,
					cards = tabletool.deepcopy(seat.cards),
				})
			end
			for _, value in ipairs(table_data.seats) do
				if seat.compared and seat.compared[value.index] then
					if value.rid > 0 and value.state ~= ESeatState.SEAT_STATE_WATCHING then
						local losediamond = 0
						if table_data.tmpdiamond.diamond and table_data.tmpdiamond.diamond[value.rid] then
							losediamond = table_data.tmpdiamond.diamond[value.rid].value
						end
						table_insert(noticemsg.compare_player_info, {
							rid = value.rid,
							seat_index = value.index,
							rolename = value.playerinfo.rolename,
							logo = value.playerinfo.logo,
							lose_money = value.diamond - value.diamond_base,
							lose_coin = table_data.tmpdiamond.coin[value.rid].value,
							lose_diamond = losediamond,
							card_type = cardtool.getCardType(value.cards) or -1,
							cards = tabletool.deepcopy(value.cards),
						})
					end
				else
					if value.index ~= seat.index then
						if value.rid > 0 and value.state ~= ESeatState.SEAT_STATE_WATCHING then
							local losediamond = 0
							if table_data.tmpdiamond.diamond and table_data.tmpdiamond.diamond[value.rid] then
								losediamond = table_data.tmpdiamond.diamond[value.rid].value
							end
							table_insert(noticemsg.compare_player_info, {
								rid = value.rid,
								seat_index = value.index,
								rolename = value.playerinfo.rolename,
								logo = value.playerinfo.logo,
								lose_money = value.diamond - value.diamond_base,
								lose_coin = table_data.tmpdiamond.coin[value.rid].value,
								lose_diamond = losediamond,
								card_type = -1,
								cards = {},
							})
						end
					end
				end
			end
			if table_data.leaves then
				for i, v in pairs(table_data.leaves) do
					if v.rid > 0 then
						if seat.compared and seat.compared[i] then
							table_insert(noticemsg.compare_player_info, v)
						else
							table_insert(noticemsg.compare_player_info, {
								rid = v.rid,
								seat_index = v.seat_index,
								rolename = v.rolename,
								logo = v.logo,
								lose_money = v.lose_money,
								lose_diamond = v.lose_diamond or 0,
								lose_coin = v.lose_coin,
								card_type = -1,
								cards = {},
							})
						end
					end
				end
			end
			balance[seat.rid] = noticemsg
			msghelper:sendmsg_to_tableplayer(seat, "gamebalanceN", noticemsg)
		end
	end
	tablelogic.save_actions(table_data, json.encode(balance))
end

function GameLogic.onegameend()
	if table_data.timer_id and table_data.timer_id >= 0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end
	if table_data.todo_time_id and table_data.todo_time_id >= 0 then
		timer.cleartimer(table_data.todo_time_id)
		table_data.todo_time_id = -1
	end
	table_data.forcecomparing = nil
	table_data.gaming = false
	table_data.balanced = true
	if table_data.conf.room_type == ERoomType.ROOM_TYPE_DIAMOND or table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_DIAMOND then
		tablelogic.change_all_player_money(table_data)
	elseif table_data.conf.room_type == ERoomType.ROOM_TYPE_COIN then
		local winseat = table_data.tmpdiamond.winseat
		table_data.tmpdiamond.winseat = nil
		local wincoinall = table_data.tmpdiamond.wincoinall
		local windiamondall = table_data.tmpdiamond.windiamondall
		table_data.tmpdiamond.coin[winseat.rid] = {
			rolename = winseat.playerinfo.rolename,
			beginvalue = math.floor(winseat.getdiamond),
			value = math.floor(wincoinall),
			endvalue = math.floor(winseat.getdiamond + wincoinall),
		}
		if table_data.tmpdiamond.windiamondall > 0 then
			table_data.tmpdiamond.diamond[winseat.rid] = {
				rolename = winseat.playerinfo.rolename,
				beginvalue = math.floor(winseat.playerinfo.diamond),
				value = math.floor(windiamondall),
				endvalue = math.floor(winseat.playerinfo.diamond + windiamondall),
			}
			winseat.playerinfo.diamond = winseat.playerinfo.diamond + table_data.tmpdiamond.windiamondall
			winseat.playerinfo.coin = winseat.playerinfo.coin - table_data.tmpdiamond.windiamondall
		end

		-- check
		local totalval = 0
		for k, v in pairs(table_data.tmpdiamond.coin) do
			totalval = totalval + v.value
		end
		for k, v in pairs(table_data.tmpdiamond.diamond or {}) do
			totalval = totalval + v.value
		end
		if totalval ~= 0 then
			filelog.sys_error("balancegame error: winseat data is not balance! msg: ", table_data.tmpdiamond)
		end

		table_data.tmpdiamond.wincoinall = nil
		table_data.tmpdiamond.windiamondall = nil
		tablelogic.change_all_player_money(table_data)
	end

	table_data.timer_id = timer.settimer(3*100, "onegamerealend")
end

function GameLogic.onegamerealend()
	table_data.the_round = table_data.the_round + 1
	if table_data.conf.room_type == ERoomType.ROOM_TYPE_DIAMOND or table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_DIAMOND then
		gamebalance(table_data)	-- 必须在重置座位状态前
		for _, value in ipairs(table_data.seats) do
			if value.state ~= ESeatState.SEAT_STATE_NO_PLAYER and value.state ~= ESeatState.SEAT_STATE_WATCHING then
				msghelper:sendmsg_to_alltableplayer("moneychangeN", {
					money_change_list = {{
						rid = value.rid,
						money_type = 2,
						value = value.diamond,
					},}
				})
			end
		end
	elseif table_data.conf.room_type == ERoomType.ROOM_TYPE_COIN then
		coingamebalance(table_data)
		for _, value in ipairs(table_data.seats) do
			if value.state ~= ESeatState.SEAT_STATE_NO_PLAYER and value.state ~= ESeatState.SEAT_STATE_WATCHING then
				msghelper:sendmsg_to_alltableplayer("moneychangeN", {
					money_change_list = {{
						rid = value.rid,
						money_type = 3,
						value = value.diamond,
					},}
				})
			end
		end
	elseif table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_FRIEND then
		gamebalance(table_data)

		for _, value in ipairs(table_data.seats) do
			if value.state ~= ESeatState.SEAT_STATE_NO_PLAYER and value.state ~= ESeatState.SEAT_STATE_WATCHING then
				if table_data.cur_games_times == 1 then
					local createcost = 0
					if not table_data.conf.card_cost_type or table_data.conf.card_cost_type == 1 then
						if value.rid == table_data.conf.create_user_rid then
							createcost = table_data.conf.create_cost
						end
					else
						createcost = math_floor(table_data.conf.create_cost/table_data.playernum)
					end
					value.fangka = createcost
				else
					value.fangka = 0
				end
			
				table_data.tablerecords = table_data.tablerecords or {}
				local onerecordmsg = {}
				onerecordmsg.rid = value.rid
				onerecordmsg.rolename = value.playerinfo.rolename
				onerecordmsg.logo = value.playerinfo.logo
				onerecordmsg.sex = value.playerinfo.sex
				onerecordmsg.highestscore = 0
				onerecordmsg.totalscore = 0
				onerecordmsg.totalwin = 0
				onerecordmsg.totallose = 0
				onerecordmsg.iswin = 0
				local hasplayerkey = 0
				for k,v in ipairs(table_data.tablerecords) do
					if v.rid == value.rid then
						hasplayerkey = k
						break
					end
				end
				-- filelog.debug("tmpdiamond data ======>>>", value.rid, table_data.tmpdiamond)
				msghelper:sendmsg_to_alltableplayer("moneychangeN", {
					money_change_list = {{
						rid = value.rid,
						money_type = 1,
						value = value.diamond,
					},}
				})
				local getscore = table_data.tmpdiamond[value.rid].value
				if hasplayerkey == 0 then
					if getscore > 0 and getscore > onerecordmsg.highestscore then
						onerecordmsg.highestscore = getscore
					end
					onerecordmsg.totalscore = onerecordmsg.totalscore + getscore
					if value.index == table_data.winer_index then
						onerecordmsg.totalwin = onerecordmsg.totalwin + 1 
					else
						onerecordmsg.totallose = onerecordmsg.totallose + 1 
					end
					table.insert(table_data.tablerecords, onerecordmsg)
				else
					local playerrecord = table_data.tablerecords[hasplayerkey]
					if playerrecord then
						if getscore > 0 and getscore > playerrecord.highestscore then
							playerrecord.highestscore = getscore
						end
						playerrecord.totalscore = playerrecord.totalscore + getscore
						playerrecord.rolename = value.playerinfo.rolename
						playerrecord.sex = value.playerinfo.sex
						if value.index == table_data.winer_index then
							playerrecord.totalwin = playerrecord.totalwin + 1 
						else
							playerrecord.totallose = playerrecord.totallose + 1 
						end
					end
				end
			end
		end
		if table_data.cur_games_times == 1 then
			tablelogic.pay_roomcard(table_data)
		end
	end

	if table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_FRIEND then
		if table_data.cur_games_times >= table_data.conf.game_times then
			local gameendmsg = {}
			local ftablebalmsg = {
				table_idx = table_data.idx,
				table_code = table_data.conf.table_code,
				fplayerinfos = {},
			}
			local records = {}
			if table_data.tablerecords then
				for key,value in pairs(table_data.tablerecords) do
					local tem = {
						rid = value.rid,  ----玩家rid
						rolename = value.rolename,
						logo = value.logo,
						highestscore = value.highestscore,
						totalscore = value.totalscore,
						totalwin = value.totalwin,
						totallose = value.totallose,
						iswin = value.iswin,
						sex = value.sex,
					}
					if tem.totalwin > tem.totallose then
						tem.iswin = 1
					elseif tem.totalwin < tem.totallose then
						tem.iswin = 0
					end
					table.insert(ftablebalmsg.fplayerinfos, tem)
					records[value.rid] = {
						rolename = tem.rolename,
						beginvalue = 0,
						value = tem.totalscore,
						endvalue = tem.totalscore,
					}
				end
			end
			table_data.enterclose = nil
			msghelper:sendmsg_to_alltableplayer("tablebalanceN", ftablebalmsg)
			-- filelog.debug("tablebalance ======>>>", ftablebalmsg)
			tablelogic.save_tablerecord(table_data, records)
		end
	end

    --游戏结束发送开奖跑马灯
    for _,msg in pairs(table_data.horseracelamps) do
        tablelogic.send_horseracelamp(msg.content)
    end

	local isallrobot = true
	local playernum = 0
	for _, seat in ipairs(table_data.seats) do
		if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			-- 结束游戏后把所有座位置为等待准备状态
			seat.state = ESeatState.SEAT_STATE_WAIT_READY
			seat.is_ready = EBOOL.FALSE
			seat.diamond_base = seat.diamond
			seat.canwinall = nil
			if not seat.isrobot then
				isallrobot = false
				playernum = playernum + 1
			end
		end
	end

	tablelogic.save_actions(table_data, "end")

	for _, seat in ipairs(table_data.seats) do
		if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			if playernum > 2 then
				if seat.isrobot then
					tablelogic.passive_standuptable(table_data, seat)
				end
			end
		end
	end

	if isallrobot then
		if table_data.conf.match_type then
			if math_random(100) <= 20 then
				table_data.delete_table_timer_id = timer.settimer(table_data.conf.retain_time*100, "delete_table")
				return
			end
		else
			table_data.delete_table_timer_id = timer.settimer(table_data.conf.retain_time*100, "delete_table")
			return
		end
	end

	if server.will_kill then
		tablelogic.leaveallplayers(table_data)
		return
	end

	-- table_data.timer_id = timer.settimer(4*100, "doreadynotice")
	GameLogic.doreadynotice()
	if table_data.conf.match_type then
		if table_data.playernum >= 2 and table_data.playernum < table_data.conf.max_player_num then
			if table_data.conf.room_type == ERoomType.ROOM_TYPE_DIAMOND then
				for i = 1, table_data.conf.max_player_num - table_data.playernum do
					msghelper:sendmsg_to_roomsvr("add_waiting_player", table_data.conf.idx, table_data.conf.match_type)
					-- filelog.warn("------ add_waiting_player ------")
				end
			elseif table_data.conf.room_type == ERoomType.ROOM_TYPE_COIN then
				for i = 1, table_data.conf.max_player_num - table_data.playernum do
					msghelper:sendmsg_to_roomsvr("add_waiting_player_coin", table_data.conf.idx, table_data.conf.match_type)
					-- filelog.warn("------ add_waiting_player_coin ------")
				end
			end
		elseif table_data.playernum < 2 then
			--匹配场
			if not table_data.recycled then
				table_data.recycled = true
				tablelogic.restart_matchtable(table_data) --匹配场，将座位上玩家，加入匹配队列
				tablelogic.leaveallplayers(table_data)
			end
			return
		end
	end

	if table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_DIAMOND then
		if table_data.cur_games_times >= table_data.conf.game_times then
			for _, seat in ipairs(table_data.seats) do
				if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
					tablelogic.passive_standuptable(table_data, seat, EStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP)
				end
			end
			return
		end
	end
end

function GameLogic.doreadynotice()
	table_data.state = ETableState.TABLE_STATE_WAIT_MIN_PLAYER
	for _, seat in ipairs(table_data.seats) do
		if seat.state ~= ESeatState.SEAT_STATE_NO_PLAYER then
			-------------------------- robot --------------------------
			-- if seat.isrobot then
			-- 	if (seat.playgamecount or 0) > 5 then
			-- 		if math_random(100) <= (seat.playgamecount - 5) * 10 then
			-- 			tablelogic.passive_standuptable(table_data, seat)
			-- 		end
			-- 	end
			-- end

			seat.ready_to_time = timetool.get_time() + table_data.conf.ready_timeout
			seat.ready_timer_id = timer.settimer(table_data.conf.ready_timeout*100, "doready", {
				rid = seat.rid,
				seat_index = seat.index,
			})
			msghelper:sendmsg_to_alltableplayer("doreadyN", {
				rid = seat.rid,
				seat_index = seat.index,
				ready_to_time = seat.ready_to_time,
				is_ready = EBOOL.FALSE,
			})
			
			-------------------------- robot test --------------------------
			if seat.isrobot then
				if seat.diamond >= table_data.conf.leave_carry_diamond then
					if msghelper:callmsg_to_roomsvr("get_game_robot_state") then
						skynet.timeout(math_random(200, 300), function()
							if seat.is_ready == EBOOL.FALSE then
								tablelogic.gameready(table_data, {rid = seat.rid}, seat)
							end
						end)
					else
						tablelogic.passive_standuptable(table_data, seat)
					end
				else
					tablelogic.passive_standuptable(table_data, seat)
				end
			end
		end
	end
end

function GameLogic.onsitdowntable(seat) --如果没有庄家，设置这个玩家为庄
	if table_data.makers == 0 then
		table_data.makers = seat.index	--报告这个参数为空
	end
end

function GameLogic.onstanduptable(seat)
	--游戏中站起处理成弃牌
	local request = {
		rid = seat.rid,
		action_type = EActionType.ACTION_TYPE_FOLD,
	}

	if tablelogic.is_onegameend(table_data) then
		return
	end

	if seat.index ~= table_data.seat_index then
		return
	end

	table_data.seat_index = GameLogic.getnextgameplayer(table_data.seat_index)
	table_data.action_to_time = timetool.get_time() + table_data.conf.action_timeout
	if table_data.seat_index then
		local doactionntcmsg = {
			rid = table_data.seats[table_data.seat_index].rid,
			seat_index = table_data.seat_index,
			action_to_time = table_data.action_to_time,
			game_turns = table_data.turns,
		}
		msghelper:sendmsg_to_alltableplayer("todoN", doactionntcmsg)
		
		table_data.state = ETableState.TABLE_STATE_WAIT_CLIENT_ACTION
		table_data.timer_id = timer.settimer(table_data.conf.action_timeout*100, "doaction", doactionntcmsg)
	end
end

function GameLogic.canendgame()
	local playingplayer = 0
	local winseat = nil
	for _, seat in ipairs(table_data.seats) do
		if GameLogic.is_playing(seat) then
			playingplayer = playingplayer + 1
			winseat = seat
		end
	end
	if playingplayer == 1 then
		table_data.winer_index = winseat.index
		table_data.winer_rid = winseat.rid
		return true, winseat
	else
		return false
	end
end

function GameLogic.is_ingame(seat) --在游戏中
	return (seat.state >= ESeatState.SEAT_STATE_PLAYING) and 
		(seat.state ~= ESeatState.SEAT_STATE_WAIT_READY) and 
		(seat.state ~= ESeatState.SEAT_STATE_WATCHING)
end

function GameLogic.is_playing(seat) --正在游戏的牌局中，去除弃牌，比牌失败等状态
	return (seat.state >= ESeatState.SEAT_STATE_PLAYING) and (seat.state < ESeatState.SEAT_STATE_FOLD)
end

function GameLogic.get_playingnum()
	local playingplayer = 0
	for _, seat in ipairs(table_data.seats) do
		if GameLogic.is_playing(seat) then
			playingplayer = playingplayer + 1
		end
	end
	return playingplayer
end

function GameLogic.pay_money(seat, action_type)
	if not seat then return end
	--[[判断是否触发奖池
	if table_data.conf.room_type == ERoomType.ROOM_TYPE_DIAMOND then
		if action_type and action_type ~= EActionType.ACTION_TYPE_FOLD then
			local openjackplayers = {}
			local card_type = cardtool.getCardType(seat.cards)
			if card_type == CardType.BAO_ZI then    --3A单独算
				if seat.cards[1].card_value == 14 then
					card_type = card_type + 1
				end
			end
			if tablelogic.check_cangetjack(card_type) then
				table_data.openjack_players = table_data.openjack_players or {}
				if not table_data.openjack_players[seat.rid] then
					
					local item = { 
						rid = seat.rid, 
						rolename = seat.playerinfo.rolename, 
						card_type = card_type, 
						table_type = table_data.conf.room_type,
						base_score = table_data.conf.base_score,
						beginvalue = seat.getdiamond,
					}
					table.insert(openjackplayers, item)
					tablelogic.handle_openjackpot(table_data, openjackplayers)
					table_data.openjack_players[seat.rid] = true
				end
			end
		end
	end
	--]]

	if table_data.conf.room_type == ERoomType.ROOM_TYPE_DIAMOND or table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_DIAMOND then
		table_data.tmpdiamond = table_data.tmpdiamond or {}
		table_data.tmpdiamond[seat.rid] = {
			rolename = seat.playerinfo.rolename,
			beginvalue = math.floor(seat.getdiamond),
			value = math.floor(seat.diamond - seat.getdiamond),
			endvalue = math.floor(seat.diamond),
			level = seat.playerinfo.level,
		}
		table_data.tmpdiamond[seat.rid].real_change = table_data.tmpdiamond[seat.rid].value
		
		if table_data.winer_rid then
			if seat.rid == table_data.winer_rid then
				--扣除抽水
				local totalwin = table_data.tmpdiamond[seat.rid].value
				local status, service_fee_rate = skynet.pcall(skynet.call, ".slotmgr", "lua", 
					"get_service_fee_rate", tablelogic.get_gamename(table_data), table_data.conf.base_score)
				local service_fee_val = math.floor((totalwin * service_fee_rate * 100) / 100 * 2)
				-- filelog.debug("service_fee_rate:", service_fee_rate, service_fee_val, totalwin)
				table_data.tmpdiamond[seat.rid].value = table_data.tmpdiamond[seat.rid].value - service_fee_val
				table_data.tmpdiamond[seat.rid].endvalue = table_data.tmpdiamond[seat.rid].endvalue - service_fee_val
				-- 还要修改身上的钱
				tablelogic.change_money(table_data, seat, -service_fee_val) --加钱

				totalwin = table_data.tmpdiamond[seat.rid].value
				if totalwin >= 500 * 100 then	--大于500，播报跑马灯
					local card_type = cardtool.getCardType(seat.cards)
					if card_type >= CardType.SHUN_ZI then
						local msg = tablelogic.get_horseracelamp(seat.playerinfo.rolename, card_type, totalwin, "元", seat.cards)
						table.insert(table_data.horseracelamps, msg)
					end
				end
			end
		end
	elseif table_data.conf.room_type == ERoomType.ROOM_TYPE_COIN then
		table_data.tmpdiamond = table_data.tmpdiamond or {coin = {}, wincoinall = 0, windiamondall = 0, winseat = nil}
		table_data.tmpdiamond.coin = table_data.tmpdiamond.coin or {}
		table_data.tmpdiamond.wincoinall = table_data.tmpdiamond.wincoinall or 0
		if seat.diamond <= seat.getdiamond then	-- 这里只计算输家
			if seat.diamond < 0 then
				table_data.tmpdiamond.diamond = table_data.tmpdiamond.diamond or {}
				table_data.tmpdiamond.coin[seat.rid] = {
					rolename = seat.playerinfo.rolename,
					beginvalue = math.floor(seat.getdiamond),
					value = -math.floor(seat.getdiamond),
					endvalue = 0,
				}
				table_data.tmpdiamond.diamond[seat.rid] = {
					rolename = seat.playerinfo.rolename,
					beginvalue = math.floor(seat.playerinfo.diamond),
					value = math.floor(seat.diamond),
					endvalue = math.floor(seat.playerinfo.diamond + seat.diamond),
				}
				table_data.tmpdiamond.wincoinall = table_data.tmpdiamond.wincoinall - table_data.tmpdiamond.coin[seat.rid].value
				table_data.tmpdiamond.windiamondall = table_data.tmpdiamond.windiamondall - table_data.tmpdiamond.diamond[seat.rid].value
			else
				table_data.tmpdiamond.coin[seat.rid] = {
					rolename = seat.playerinfo.rolename,
					beginvalue = math.floor(seat.getdiamond),
					value = math.floor(seat.diamond - seat.getdiamond),
					endvalue = math.floor(seat.diamond),
				}
				table_data.tmpdiamond.wincoinall = table_data.tmpdiamond.wincoinall - table_data.tmpdiamond.coin[seat.rid].value
			end
		else
			table_data.tmpdiamond.winseat = seat
		end
	elseif table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_FRIEND then
		table_data.tmpdiamond = table_data.tmpdiamond or {}
		table_data.tmpdiamond[seat.rid] = {
			rolename = seat.playerinfo.rolename,
			beginvalue = math.floor(seat.getdiamond),
			value = math.floor(seat.diamond - seat.getdiamond),
			endvalue = math.floor(seat.diamond),
		}
	end

	seat.getdiamond = seat.diamond
	if table_data.conf.room_type == ERoomType.ROOM_TYPE_DIAMOND or table_data.conf.room_type == ERoomType.ROOM_TYPE_ZJ_DIAMOND then
		seat.playerinfo.diamond = seat.diamond
	elseif table_data.conf.room_type == ERoomType.ROOM_TYPE_COIN then
		seat.playerinfo.coin = seat.diamond
		if seat.diamond < 0 then
			seat.playerinfo.diamond = seat.playerinfo.diamond - seat.diamond
			seat.playerinfo.coin = 0
		end
	end
end

--//游戏开始，初始化位置信息
function GameLogic.onegamestart_initseat(seat)
	seat.state = ESeatState.SEAT_STATE_PLAYING
	seat.timeout_count = 0
	seat.ready_to_time = 0
	
	seat.seecards = 0   	--是否看牌
	seat.diamond_base = seat.diamond --记录当前的金币数
	seat.compared = nil
	seat.action_times = 0
	seat.comparewin = 0
	table_data.robotdata.seats[seat.index].actioncount = 0
	
	tablelogic.change_money(table_data, seat, -table_data.cur_bets)	--扣除底注   	
	table_data.all_bets = table_data.all_bets + table_data.cur_bets
end

function GameLogic.onegamestart_inittable()
	table_data.seat_index = 0
	table_data.action_to_time = 0
	table_data.action_type = 0
	table_data.action_cards = nil
	table_data.cur_bets = table_data.conf.base_score--当前下注
	table_data.winer_rid = nil

	table_data.all_bets = 0						--所有的注
	table_data.turns = 0   						--当前游戏圈数
	table_data.playernum = 0
	table_data.start_playernum = 0
	table_data.tmpdiamond = nil
	table_data.gamerecords = {}
	table_data.tip = nil
	table_data.leaves = nil
	table_data.balanced = nil
	table_data.comparing = nil
	table_data.horseracelamps = {}
	table_data.robotdata.raisevalue = 1
	table_data.robotdata.seecardscount = 0

	if table_data.timer_id and table_data.timer_id >= 0 then
		timer.cleartimer(table_data.timer_id)
		table_data.timer_id = -1
	end
	if table_data.todo_time_id and table_data.todo_time_id > 0 then
		timer.cleartimer(table_data.todo_time_id)
		table_data.todo_time_id = -1
	end
	-- if table_data.conf.game_type > 2 then
	-- 	table_data.turns = 3
	-- end
end

function GameLogic.standup_clear_seat(seat)
	seat.rid = 0
	seat.playerinfo = {}
	seat.state = ESeatState.SEAT_STATE_NO_PLAYER
	seat.cards = {}
	seat.is_tuoguan = EBOOL.FALSE
	seat.timeout_count = 0
	seat.diamond = 0	--玩家携带进桌的金币
	seat.getdiamond = 0
	seat.is_ready = EBOOL.FALSE
	seat.seecards = 0
	seat.diamond_base = 0
	seat.entercarry = 0
	seat.compared = nil
	seat.action_times = 0
	seat.remindermoneyCD = nil
	seat.isrobot = nil
	seat.istest = nil
	seat.canwinall = nil
	if seat.ready_timer_id and seat.ready_timer_id > 0 then
		timer.cleartimer(seat.ready_timer_id)
		seat.ready_timer_id = -1
	end
end

return GameLogic
